package ru.adhoc.truealarm.time;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.text.format.DateFormat;
import android.util.Log;
import android.widget.Toast;

import java.util.Calendar;

import ru.adhoc.truealarm.R;
import ru.adhoc.truealarm.alarmreceiver.AlarmManagerBroadcastReceiver;
import ru.adhoc.truealarm.db.DbHelper;
import ru.adhoc.truealarm.notification.NfHelper;

/**
 * Created by Малюгин Сергей on 26.07.13.
 */
public class TimeHelper {

    DbHelper DbHelper;
    public int currentRepeat = 0;
    private boolean is24HourFormat;

    private static TimeHelper instance;
    Context context;

    public TimeHelper(Context c) {
        context = c;
        DbHelper = DbHelper.getInstance(context);
        is24HourFormat = DateFormat.is24HourFormat(context);
    }

    public static TimeHelper getInstance(Context ctx){
        if (instance == null){
            instance = new TimeHelper(ctx);
        }
        return instance;
    }

//show toast "you can sleep"
    public void showAlarmToast(long time){

        Calendar cl = Calendar.getInstance();
        Long diffTime = time - cl.getTimeInMillis();
        long days = diffTime/(1000*60*60*24);
        long hours = (diffTime - (days * 86400000))/(1000*60*60);
        long minutes = (diffTime -(days * 86400000)- (hours*1000*60*60))/(1000*60);
        //long sec = (diffTime - (days * 86400000)- (hours*1000*60*60)- (minutes*1000*60))/1000;

        if(days !=0){
        String msg =
                context.getString(R.string.YouCanSleep)
                        +" "+days
                        +context.getString(R.string.d)
                        +" "+hours
                        +context.getString(R.string.h)
                        +" "+minutes
                        +context.getString(R.string.min);
        Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
        }
        else {
            String msg =
                    context.getString(R.string.YouCanSleep)
                            +" "+hours
                            +context.getString(R.string.h)
                            +" "+minutes
                            +context.getString(R.string.min);
            Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
        }
    }

//Процедура перезаводит будильник на заданное количество мсек
    public void resetAlarmTimeByInterval(int id){

        //Получаем время будильника:
        SQLiteDatabase db = DbHelper.getReadableDatabase();
        int minutes = 1;

        try{
            Cursor c = DbHelper.getOnesAlarm(db, id);
            if(c.moveToFirst())
                minutes = c.getInt(c.getColumnIndex("interval"));
            c.close();
        }
        finally {
            if(db != null)
                db.close();
        }

        Long newTime = Calendar.getInstance().getTimeInMillis() + (minutes * 1000 * 60);

        //Грохаем текущий ресивер
        AlarmManagerBroadcastReceiver alarm = new AlarmManagerBroadcastReceiver();
        alarm.CancelAlarm(context,id);

        //Создаём новый ресивер
        alarm.SetAlarm(context, newTime, id);

        //Обновляем нотификацию
        NfHelper.getInstance(context).showNotificationService(newTime, true);
    }

    private int[][] getDateEqualsArray(){
        int[][] arr = new int[7][2];

        arr[0][0] = 6;//вс
        arr[0][1] = 0;

        arr[1][0] = 0;//пн
        arr[1][1] = 1;

        arr[2][0] = 1;//вт
        arr[2][1] = 2;

        arr[3][0] = 2;//ср
        arr[3][1] = 3;

        arr[4][0] = 3;//чт
        arr[4][1] = 4;

        arr[5][0] = 4;//пт
        arr[5][1] = 5;

        arr[6][0] = 5;//сб
        arr[6][1] = 6;

        return arr;
    }

//Возвращает по йдишнику время когда должен сработать будильник если его включить сейчас
    public Long getActualTimeForAlarmByID(int id){

//Получаем  дата/время будильника и строку повторов
        SQLiteDatabase db = DbHelper.getWritableDatabase();
        Long time = 0L;
        String repDays = "";

        try {
            Cursor c = DbHelper.getOnesAlarm(db,id);
            if(c.moveToFirst()){
                time = c.getLong(c.getColumnIndex("time"));
                repDays = c.getString(c.getColumnIndex("repdays"));
            }
            c.close();
        }
        finally {
            if(db != null)
                db.close();
        }

//присваеваем календарю время будильника и получаем из него чаcы и минуты
        Calendar alCl = Calendar.getInstance();
        alCl.setTimeInMillis(time);
        int hour = alCl.get(Calendar.HOUR_OF_DAY);
        int min = alCl.get(Calendar.MINUTE);

//Получаем текущую дату и подставляем туда чамы и минуты будильника
        Calendar cl = Calendar.getInstance();
        cl.set(Calendar.HOUR_OF_DAY,hour);
        cl.set(Calendar.MINUTE,min);
        cl.set(Calendar.SECOND,0);
        cl.set(Calendar.MILLISECOND,0);

        ///////////////////////////////////////////////////////////////////////////////////////

//Время будильника приведённое к текущей дате и ткущий день недели
        Long alarmTime = cl.getTimeInMillis();
        int currentDayOfWeek = cl.get(Calendar.DAY_OF_WEEK);

        int alarmDayS = -1;
        int alarmDayC = -1;

//массив соответствий дней календаря и строки дат [i][j] j= формат строки i = формат календаря
        int[][] arrEq = getDateEqualsArray();


//Проходимся циклом по массиву дней в направлении от текущего дня до конце недели
        //если не находим в строке повтороений наш день то идём дальше ->
        for(int i = currentDayOfWeek; i <= 6; i++){
            int timeStringDay = arrEq[i][0];
            int timeStringCal = arrEq[i][1];
            if(repDays.indexOf(Integer.toString(timeStringDay)) == -1){
                alarmDayS = timeStringDay;
                alarmDayC = timeStringCal+1;
                break;
            }
        }

//Если в прошлом цикле мы не нашли день для срабатывания будильника то идём по строке повторов
        //в направлении к концу недели
        if(alarmDayS == -1){
            for(int i = 0; i <= currentDayOfWeek; i++){
                int timeStringDay = arrEq[i][0];
                int timeStringCal = arrEq[i][1];
                if(repDays.indexOf(Integer.toString(timeStringDay)) == -1){
                    alarmDayS = timeStringDay;
                    alarmDayC = timeStringCal+1;
                    break;
                }
            }
        }

        int oneDayMSEC = 86400000;
        int daysToReset;

        if(alarmDayC <= currentDayOfWeek)
            daysToReset = (7-currentDayOfWeek)+alarmDayC;
        else
            daysToReset = alarmDayC - currentDayOfWeek;

        int currDayOfWeek = arrEq[currentDayOfWeek-1][0];
        if(repDays.indexOf(Integer.toString(currDayOfWeek)) == -1){
            Long currTime = Calendar.getInstance().getTimeInMillis();
            if(currTime < alarmTime){
                daysToReset = 0;
            }
        }

        int timeDiffToResetMSEC = daysToReset * oneDayMSEC;
        Long newAlarmTime = alarmTime + timeDiffToResetMSEC;

//        //отладочаня тема потом удалить!!!!
//        Calendar cal = Calendar.getInstance();
//        cal.setTimeInMillis(newAlarmTime);
//        int day = cal.get(Calendar.DAY_OF_MONTH);
//        int h = cal.get(Calendar.HOUR_OF_DAY);
//        int m =cal.get(Calendar.MINUTE);
//        Log.d("My", "getActualTimeForAlarmByID сработает в - " + day + " числа "+h+"ч "+m+"мин ");
//        //отладочаня тема потом удалить!!!!

        return newAlarmTime;
    }

//Возвращает актуальное время срабатывания будильнкика по времени и строке повторов
    public Long getActualTimeForAlarmByTime(Long alarmTime, String repDays){

//Время будильника приведённое к текущей дате и ткущий день недели
        Calendar cl = Calendar.getInstance();
        int currentDayOfWeek = cl.get(Calendar.DAY_OF_WEEK);

        int alarmDayS = -1;
        int alarmDayC = -1;

//массив соответствий дней календаря и строки дат [i][j] j= формат строки i = формат календаря
        int[][] arrEq = getDateEqualsArray();

        for(int i = currentDayOfWeek; i <= 6; i++){
            int timeStringDay = arrEq[i][0];
            int timeStringCal = arrEq[i][1];
            if(repDays.indexOf(Integer.toString(timeStringDay)) == -1){
                alarmDayS = timeStringDay;
                alarmDayC = timeStringCal+1;
                break;
            }
        }

        if(alarmDayS == -1){
            for(int i = 0; i <= currentDayOfWeek; i++){
                int timeStringDay = arrEq[i][0];
                int timeStringCal = arrEq[i][1];
                if(repDays.indexOf(Integer.toString(timeStringDay)) == -1){
                    alarmDayS = timeStringDay;
                    alarmDayC = timeStringCal+1;
                    break;
                }
            }
        }

        int oneDayMSEC = 86400000;
        int daysToReset;

        if(alarmDayC <= currentDayOfWeek)
            daysToReset = (7-currentDayOfWeek)+alarmDayC;
        else
            daysToReset = alarmDayC - currentDayOfWeek;

        int currDayOfWeek = arrEq[currentDayOfWeek-1][0];
        if(repDays.indexOf(Integer.toString(currDayOfWeek)) == -1){
            Long currTime = Calendar.getInstance().getTimeInMillis();
            if(currTime < alarmTime){
                daysToReset = 0;
            }
        }

        int timeDiffToResetMSEC = daysToReset * oneDayMSEC;
        Long newAlarmTime = alarmTime + timeDiffToResetMSEC;
        return newAlarmTime;
    }

    public String getTimeStringForDisplay(Long time){
        String timeString;
        if(is24HourFormat)
            timeString = createTimeString24h(time);
        else
            timeString = createTimeString12h(time);
        return timeString;
    }

    //crete time string 24h format
    private String createTimeString24h(Long time){
        Calendar cl = Calendar.getInstance();
        cl.setTimeInMillis(time);
        String hour = convertTimeToString24h(cl.get(Calendar.HOUR_OF_DAY));
        String min = convertTimeToString24h(cl.get(Calendar.MINUTE));
        String timeForList = hour + ":" + min;
        return  timeForList;
    }

    private String createTimeString12h(Long time){
        Calendar cl = Calendar.getInstance();
        cl.setTimeInMillis(time);
        int hour24 = cl.get(Calendar.HOUR_OF_DAY);
        String hour = convertTimeToString24h(cl.get(Calendar.HOUR));
        String min = convertTimeToString24h(cl.get(Calendar.MINUTE));

        if(hour24 == 12 || hour24 == 0)
            hour = "12";

        String timeForList = hour + ":" + min;
        return timeForList;
    }

    public String getAMPM(Long time){
        Calendar cl = Calendar.getInstance();
        cl.setTimeInMillis(time);

        if(!is24HourFormat)
            return cl.get(Calendar.AM_PM) == 0 ? "AM" : "PM";
        else
            return "";
    }

    //convert 1 -> 01
    private String convertTimeToString24h(int num){
        String r;
        if(num == 0) r = "00";
        else if (num <= 9) r = "0"  + Integer.toString(num);
        else r = Integer.toString(num);
        return r;
    }

    public  String getDateStringForDisplay(Long time){
        Calendar cl = Calendar.getInstance();
        cl.setTimeInMillis(time);
        int day = cl.get(Calendar.DAY_OF_MONTH);
        int month  = cl.get(Calendar.MONTH)+1;
        int year = cl.get(Calendar.YEAR);
        return ""+day+"."+month+"."+year;
    }

}


